/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.udt.designtime.manager.generatecmpcode.javacodegenerator;


import com.google.common.util.concurrent.ServiceManager;
import com.inspur.edp.bef.component.base.GspComponent;
import com.inspur.edp.cef.designtime.api.operation.CommonOperation;
import com.inspur.edp.cef.designtime.api.operation.CommonOperation;
import com.inspur.edp.lcm.metadata.api.IMetadataContent;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.service.RefCommonService;
import com.inspur.edp.udt.designtime.api.entity.UnifiedDataTypeDef;
import com.inspur.edp.udt.designtime.api.utils.UdtUtils;
import com.inspur.edp.udt.designtime.manager.generatecomponent.*;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;

public abstract class JavaBaseCommonCompCodeGenerator {

  ///#region 字段
  private String entitynameSpace;
  private String apinameSpace;


  protected CommonOperation operation;
  protected String nameSpace;
  protected String entityClassName;
  protected String code;
  protected String packageName;

  private String privatePath;

  public final String getPath() {
    return privatePath;
  }

  public final void setPath(String value) {
    privatePath = value;
  }

  private RefCommonService lcmDtService;

  private RefCommonService getLcmDtService() {
    if (lcmDtService == null) {
      lcmDtService = SpringBeanUtils.getBean(RefCommonService.class);
    }
    return lcmDtService;
  }

  protected abstract String getBaseClassName();

  ///#region 构造函数
  protected JavaBaseCommonCompCodeGenerator(UnifiedDataTypeDef udtDef, CommonOperation operation,
      String nameSpace, String path) {
    this.code = udtDef.getCode();
    this.packageName = udtDef.getDotnetAssemblyName();
    setPath(path);
    this.operation = operation;
    //nameSpace = getnameSpace(nameSpace);
    this.nameSpace = getnameSpace();
    this.entityClassName = udtDef.getGeneratedEntityClassInfo().getClassName();
    this.entitynameSpace = udtDef.getGeneratedEntityClassInfo().getClassNamespace();
    this.apinameSpace = udtDef.getApiNamespace().getDefaultNamespace();
  }

  private String getnameSpace(String basenameSpace) {
    String nameSpace = "%1$s.%2$s";
    return String.format(nameSpace, basenameSpace + "." + code, getNameSpaceSuffix());
  }

  private String getnameSpace() {
    String nameSpace = "%1$s.%2$s";
    return String.format(nameSpace, packageName + "." + code, getNameSpaceSuffix());
  }

  protected abstract String getNameSpaceSuffix();

  /**
   * 获取当前构件名称
   */
  public final String getCompName() {
    if (UdtUtils.checkNull(operation.getComponentId())) {
      return getInitializeCompName();
    }
    GspMetadata metadata = getLcmDtService().getRefMetadata(operation.getComponentId());
    if (metadata == null) {
      throw new RuntimeException("没有生成构件，无法继续生成代码");
    }

    IMetadataContent content = metadata.getContent();
    String fullClassName = "";
    if (content instanceof GspComponent) {
      GspComponent component = (GspComponent) ((metadata.getContent() instanceof GspComponent)
          ? metadata.getContent() : null);
      fullClassName = component.getMethod().getDotnetClassName();
    } else {
      throw new RuntimeException("当前元数据不属于构件元数据");
    }

    String[] sections = fullClassName.split("[.]", -1);
    return sections[sections.length - 1];
  }

  ///#endregion

  ///#region 转换Java包名
  private String convertJavaImportPackage(String assemblyName) {
    return ComponentGenUtil.prepareJavaPackageName(assemblyName);
  }

  ///#endregion

  /**
   * 生成构件代码
   * @return
   */
  public final String generate() {
    StringBuilder result = new StringBuilder();

    ///#region package
    nameSpace = convertJavaImportPackage(nameSpace);
    result.append(JavaCompCodeNames.KeywordPackage).append(" ").append(nameSpace).append(";")
        .append(getNewline());

    ///#endregion
    ///#region import
    generateImport(result);
    result.append("\n");

    ///#endregion
    ///#region ClassStart
    result.append(JavaCompCodeNames.KeywordPublic).append(" ")
        .append(JavaCompCodeNames.KeywordClass).append(" ").append(getCompName()).append(" ")
        .append(JavaCompCodeNames.KeywordExtends).append(" ").append(getBaseClassName()).append(" ")
        .append("{").append(getNewline());

    ///#endregion
    ///#region Field

    javaGenerateField(result);
    result.append("\n");

    ///#endregion
    ///#region Constructor

    javaGenerateConstructor(result);
    result.append("\n");

    ///#endregion

    ///#region ExecuteMethod
    result.append(getIndentationStr()).append("@").append(JavaCompCodeNames.KeywordOverride)
        .append(getNewline());
    result.append(getIndentationStr()).append(JavaCompCodeNames.KeywordPublic).append(" ")
        .append(JavaCompCodeNames.KeywordVoid).append(" ").append("execute()").append(" ")
        .append("{").append(getNewline());

    result.append(getIndentationStr()).append("}").append(getNewline());
    ///#endregion
    ///#region ExtendMethod

    javaGenerateExtendMethod(result);

    ///#endregion
    ///#region ClassEnd
    result.append(getNewline()).append("}");

    ///#endregio
    return result.toString();
  }

  ///#region 生成方法

  /**
   * 生成Using代码
   */

  private void generateImport(StringBuilder result) {
//		entitynameSpace = String.format("%1$s%2$s",convertJavaImportPackage(entitynameSpace),".*");
    entitynameSpace = String.format("%1$s%2$s", entitynameSpace, ".*");

    result.append(getImportStr(entitynameSpace));
//		apinameSpace = String.format("%1$s%2$s",convertJavaImportPackage(apinameSpace),".*");
    apinameSpace = String.format("%1$s%2$s", apinameSpace, ".*");
    result.append(getImportStr(apinameSpace));
    javaGenerateExtendUsing(result);
  }

  protected abstract void javaGenerateExtendUsing(StringBuilder result);

  protected abstract void javaGenerateConstructor(StringBuilder result);

  /**
   * 生成扩展操作
   * @param result
   */
  protected void javaGenerateExtendMethod(StringBuilder result) {

  }

  protected void javaGenerateField(StringBuilder result) {

  }

  ///#endregion
  ///#region 通用方法
  protected final String getImportStr(String value) {
    return new StringBuilder(JavaCompCodeNames.KeywordImport).append(" ").append(value).append(";")
        .append(getNewline()).toString();
  }

  protected final String getNewline() {
    return "\r\n";
  }

  /**
   * 缩进
   */
  protected final String getIndentationStr() {
    return "\t";
  }

  /**
   * 双缩进
   */
  protected final String getDoubleIndentationStr() {
    return "\t\t";
  }

  ///#endregion

  protected abstract String getInitializeCompName();
}
